<template>
  <el-container style="width: 100%; height: 100%">
    <el-header class="header"> 相机轨道 </el-header>
    <el-main class="canvas-container">
      <canvas ref="canvas" class="canvas"></canvas>
    </el-main>
  </el-container>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import * as THREE from 'three'

let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let renderer: THREE.WebGLRenderer
let animationFrameId: number
let angle = 0
const canvas = ref<HTMLCanvasElement>()

onMounted(() => {
  initScene()
  animate()
  // 添加窗口大小改变事件监听
  window.addEventListener('resize', onWindowResize)
})

function initScene() {
  if (!canvas.value) return
  const width = canvas.value.clientWidth
  const height = canvas.value.clientHeight
  console.log(width, height)
  scene = new THREE.Scene()
  // 设置场景背景颜色 红色
  scene.background = new THREE.Color(0xf0f0f0)
  camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
  renderer = new THREE.WebGLRenderer({ canvas: canvas.value })

  const cube1 = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0x00ff00 }),
  )
  cube1.position.set(0, 0, 0)
  scene.add(cube1)

  const cube2 = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0x0000ff }),
  )
  cube2.position.set(2, 0, 0)
  scene.add(cube2)
  renderer.setSize(width, height)
  renderer.setPixelRatio(window.devicePixelRatio)
  camera.position.set(0, 4, 5)
}

function animate() {
  animationFrameId = requestAnimationFrame(animate)
  angle += 0.01
  const radius = 5
  camera.position.x = radius * Math.cos(angle)
  camera.position.z = radius * Math.sin(angle)
  camera.lookAt(0, 0, 0)
  renderer.render(scene, camera)
}

// 清理函数
function cleanup() {
  // 取消动画帧
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId)
  }

  // 清理渲染器
  if (renderer) {
    // 移除所有事件监听器
    renderer.domElement.removeEventListener('resize', onWindowResize)
    // 释放渲染器资源
    renderer.dispose()
    // 清空渲染器
    renderer.forceContextLoss()
    // 移除画布
    renderer.domElement.remove()
  }

  // 清理场景
  if (scene) {
    // 遍历场景中的所有对象
    scene.traverse((object) => {
      if (object instanceof THREE.Mesh) {
        // 释放几何体资源
        object.geometry.dispose()
        // 释放材质资源
        if (Array.isArray(object.material)) {
          object.material.forEach((material) => material.dispose())
        } else {
          object.material.dispose()
        }
      }
    })
    // 清空场景
    scene.clear()
  }

  // 清理相机
  if (camera) {
    camera.clear()
  }
}

// 窗口大小改变时的处理函数
function onWindowResize() {
  if (!canvas.value) return
  const width = canvas.value.clientWidth
  const height = canvas.value.clientHeight

  // 更新相机
  camera.aspect = width / height
  camera.updateProjectionMatrix()

  // 更新渲染器
  renderer.setSize(width, height)
}

onUnmounted(() => {
  cleanup()
  // 移除窗口大小改变事件监听
  window.removeEventListener('resize', onWindowResize)
})
</script>
<style scoped>
.header {
  text-align: center;
  font-size: 20px;
  font-weight: bold;
  color: #333;
}
.canvas-container {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}
.canvas {
  width: 100%;
  height: 100%;
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
</style>
